<template>
  <div class="user_list">
    <!-- 创建按钮 -->
    <a-card>
      <div class="user_title">
        <span>用户列表</span>
        <a-button type="primary" class="set_up" @click="onSetUpUser" icon="plus" v-action:add="'user'">新建</a-button>
      </div>
      <!-- 表格 -->
      <a-table
        :columns="columns"
        :data-source="userTableData"
        :pagination="currentConfig"
        :scroll="{x: true}"
        @change="onTableHandle"
        :loading="table_loading"
        rowKey="id"
        style="margin-top:24px;"
      >
        <span slot="action" slot-scope="row" class="user_action">
          <a @click="onUpdateUser(row)" v-action:edit="{role: 'user', id: row.id}">编辑</a>
          <a-divider type="vertical" style="opacity: 0;" />
          <a @click="onDeleteUser(row)" v-action:delete="'user'">删除</a>
        </span>
      </a-table>
    </a-card>
    <a-modal
      :title="title"
      :visible="visible"
      :maskClosable="false"
      :confirm-loading="permissionForm.loadingBtn"
      @cancel="onClose"
      :footer="null"
      width="35%"
    >
      <!-- 表单 -->
      <a-form-model
        v-if="currentShow == 'user'"
        ref="ruleForm"
        :model="form.data"
        :rules="rules"
        :label-col="{ xl: {span: 4}, lg: { span: 5 } }"
        :wrapper-col="{ xl: {span: 20}, lg: { span: 19 } }"
      >
        <!-- 用户名 -->
        <a-form-model-item ref="username" label="用户名" prop="username">
          <span v-if="form.data.id">{{form.data.username}}</span>
          <a-input v-else v-model="form.data.username" placeholder="请输入用户名" />
        </a-form-model-item>
        <!-- 密码 -->
        <a-form-model-item ref="password" label="密码" prop="password">
          <a-input-password v-model="form.data.password" placeholder="请输入密码"/>
        </a-form-model-item>
        <!-- 确认密码 -->
        <a-form-model-item ref="password2" label="确认密码" prop="password2">
          <a-input-password v-model="form.data.password2" placeholder="请再次输入密码"/>
        </a-form-model-item>
        <!-- 手机号 -->
        <a-form-model-item ref="phone" label="手机号" prop="phone">
          <a-input v-model="form.data.phone" placeholder="请输入手机号"/>
        </a-form-model-item>
        <!-- 邮箱 -->
        <a-form-model-item ref="email" label="邮箱" prop="email">
          <a-input v-model="form.data.email" placeholder="请输入邮箱"/>
        </a-form-model-item>
        <!-- 角色 -->
        <a-form-model-item label="角色" prop="roleIds">
          <a-select
            mode="multiple"
            style="width: 100%"
            placeholder="请选择角色"
            v-model="form.data.roleIds"
          >
            <a-select-option :value="item.id" :name="item.name" v-for="(item,index) in roleList" :key="index">
              {{ item.displayName }}
            </a-select-option>
          </a-select>
        </a-form-model-item>
        <!-- 组织机构 -->
        <a-form-model-item label="组织机构" prop="orgIds" v-if="showOrgSelection">
          <a-tree-select
            v-model="form.data.orgIds"
            style="width: 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            :tree-data="orgTreeData"
            :replace-fields="replaceFields"
            placeholder="请选择组织机构"
            tree-default-expand-all
            allow-clear
            multiple
            show-search
          >
          </a-tree-select>
        </a-form-model-item>
        <!-- 说明 -->
        <a-form-model-item label="说明" prop="remark">
          <a-input v-model="form.data.remark" type="textarea" placeholder="写一段说明" />
        </a-form-model-item>
        <a-form-model-item label="启用状态" prop="active" v-if="form.data.id">
          <a-switch v-model="form.data.active" checked-children="启用" un-checked-children="禁用" default-checked />
        </a-form-model-item>
        <!-- 提交 -->
        <a-form-model-item class="submit_style" :wrapper-col="{ span: 24 }">
          <a-divider />
          <a-button
            class="save_button"
            type="primary"
            @click="onSubmit"
            :loading="form.loadingBtn"
            :disabled="form.statusBtn"
          >
            保存
          </a-button>
          <a-button class="cancal_button" @click="onClose">
            取消
          </a-button>
        </a-form-model-item>
      </a-form-model>

      <!--  -->
      <a-form-model
        v-if="currentShow == 'data'"
        :model="permissionForm.data"
        :label-col="{ span: 4 }"
        :wrapper-col="{ span: 20 }"
      >
        <a-form-model-item label="分配数据源" prop="permission">
          <a-select
            mode="multiple"
            style="width: 100%"
            placeholder="请选择数据源"
            v-model="permissionForm.data.permission"
            :disabled="permissionForm.isLook"
          >
            <a-select-option v-for="data in datasourceList" :key="data.id" :value="data.id">
              {{ data.name }}
            </a-select-option>
          </a-select>
        </a-form-model-item>
        <a-form-model-item class="submit_style" :wrapper-col="{ span: 24 }">
          <a-divider />
          <a-button
            class="save_button"
            type="primary"
            v-show="!permissionForm.isLook"
            @click="onSubmitUserPermission"
            :loading="permissionForm.loadingBtn"
            :disabled="permissionForm.statusBtn"
          >
            保存
          </a-button>
          <a-button class="save_button" type="primary" v-show="permissionForm.isLook" @click="onAgainSetUserPermission">
            重新分配
          </a-button>
          <a-button class="cancal_button" @click="visible = false">
            关闭
          </a-button>
        </a-form-model-item>
      </a-form-model>

      <!--  -->
      <a-form-model
        v-if="currentShow == 'menu'"
        :model="permissionForm.menu"
        :label-col="{ span: 4 }"
        :wrapper-col="{ span: 20 }"
      >
        <a-form-model-item label="分配权限" prop="permission">
            <a-tree-select
              show-search
              style="width: 100%"
              v-model="permissionForm.menu.permission"
              placeholder="请选择权限"
              allow-clear
              multiple
              tree-default-expand-all
              :disabled="permissionForm.isLook"
              @change="onTreeSelectChange"
            >
              <a-tree-select-node v-for="tree in treedPermissions" :key="tree.key" :value="tree.value" :title="tree.title">
                <template v-if="tree.children && tree.children.length">
                  <a-tree-select-node v-for="item in tree.children" :key="item.key" :value="item.value" :title="item.title">
                  </a-tree-select-node>
                </template>
              </a-tree-select-node>
            </a-tree-select>
        </a-form-model-item>
        <a-form-model-item class="submit_style" :wrapper-col="{ span: 24 }">
          <a-divider />
          <a-button
            class="save_button"
            type="primary"
            v-show="!permissionForm.isLook"
            @click="onSubmitUserPermission"
            :loading="permissionForm.loadingBtn"
            :disabled="permissionForm.statusBtn"
          >
            保存
          </a-button>
          <a-button class="save_button" type="primary" v-show="permissionForm.isLook" @click="onAgainSetUserPermission" :loading="permissionForm.loadingBtn">
            重新分配
          </a-button>
          <a-button class="cancal_button" @click="visible = false">
            关闭
          </a-button>
        </a-form-model-item>
      </a-form-model>
    </a-modal>
  </div>
</template>

<script>
import { mapActions, mapMutations, mapState } from 'vuex';
import { baseMixin } from '@/store/app-mixin';
import store from '@/store'
import {ROLE_ADMIN} from "@/store/mutation-types";
const columns = [
        { title: '用户id', dataIndex: 'id' },
        { title: '用户名', dataIndex: 'username', sorter: true },
        { title: '手机号', dataIndex: 'phone', sorter: true },
        { title: '邮箱', dataIndex: 'email', sorter: true },
        { title: '角色', dataIndex: 'role' },
        { title: '说明', dataIndex: 'remark' },
        { title: '创建时间', dataIndex: 'createdAt' },
        { title: '更新时间', dataIndex: 'updatedAt' },
        { title: '操作', fixed: 'right', scopedSlots: { customRender: 'action' } }
      ]

  export default {
    name: 'UserList',
    mixins: [baseMixin],
    data () {
      // 自定义校验密码
      const validatePassPassword = (rule, value, callback) => {
        this.password = value
        const regex = new RegExp('^.*(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*?])'),
            PassWordStatus = regex.test(value)
        if (this.title == '新增用户') {
          if (!value) {
            callback('请输入密码')
          } else if (!PassWordStatus) {
            callback('密码必须包含数字、大小写字母和特殊符号')
          } else {
            callback()
          }
        } else {
          if (value && PassWordStatus || value == undefined) {
            callback()
          } else {
            callback('密码格式不规范')
          }
        }

      }
      // 确认密码校验
      const validatePassPassword2 = (rule, value, callback) => {
        if (this.title == '修改用户') {
          if (value == undefined && !this.password) {
            callback()
          } else if(value == this.password) {
            callback()
          } else {
            callback('两次密码输入不一致')
          }
        } else {
          if (value) {
            if (this.password === value) {
              callback()
            } else {
              callback('两次密码输入不一致')
            }
          } else {
            callback('请再次输入密码')
          }
        }

      }

      return {
        columns,
        visible: false,
        title: '新增用户',
        table_loading: false,
        form: {
          loadingBtn: false,
          statusBtn: false,
          data: {
            roleIds: [],
            orgIds: []
          }
        },
        permissionForm: {
          isLook: true,
          statusBtn: false,
          loadingBtn: false,
          data: {
            permission:[]
          },
          menu: {
            permission:[]
          }
        },
        autoExpandParent: true,
        selectedKeys: [],
        navMenu: [],
        datasourceList: [],
        roleList: [],
        password:'',
        currentShow: 'user',
        rules: {
          username: [
            { required: true, message: '请输入用户名', trigger: 'blur' },
            { min: 4, max: 20, message: '用户名长度在4-20位之间', trigger: 'blur'}
          ],
          password: [ { validator: validatePassPassword, trigger: 'blur'}, { max: 50, message: '密码长度不能超过50位', trigger: 'blur'} ],
          password2: [ { validator: validatePassPassword2, trigger: 'blur'}, { max: 50, message: '密码长度不能超过50位', trigger: 'blur'} ],
          email: [ { message: '您输入的邮箱格式不规范', pattern: /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,4}$/, trigger: 'blur' } ],
          phone: [ { message: '您输入的手机号格式不规范', pattern: /^1[3|4|5|7|8]\d{9}$/, trigger: 'blur' } ],
          roleIds: [ { type: 'array', required: true, message: '请至少选择一项角色', trigger: 'change' } ],
          remark: [ { max: 255, trigger: 'blur', message: '最大长度不能超过255个字符' } ],
          orgIds:[{ required: true, message: '请选择用户所属组织机构', trigger: 'blur' },]
        },
        showOrgSelection: false,
        orgTreeData:[]
      }
    },
    watch: {
      // 关闭抽屉清空表单
      visible (val) {
        if (!val) {
          this.form.data = { roleIds: [],orgIds: [] }
          this.permissionForm = {
            isLook: true,
            statusBtn: false,
            loadingBtn: false,
            data: {
              permission:[]
            },
            menu: {
              permission:[]
            }
          }
          this.password = ''
          this.$refs.ruleForm && this.$refs.ruleForm.clearValidate()
        }
      }
    },
    computed: {
      ...mapState('userManage',['userList', 'currentConfig','replaceFields']),
      userTableData () {
        return this.userList.map(user => {
          let role = [],
              roleIds = user.roleIds
          for (let i=0; i<this.roleList.length; i++) {
            for (let j=0; j<roleIds.length; j++) {
              if (this.roleList[i].id == roleIds[j]) {
                role.push(this.roleList[i].displayName)
              }
            }
          }
          return {...user, role: role.join()}
        })
      },
      treedPermissions () {
        if (this.navMenu.length) {
          return this.generateTree(this.navMenu)
        } else {
          return []
        }
      },
    },
    mounted () {
      const roles = store.getters.roles
      if (roles  && roles.indexOf(ROLE_ADMIN) > -1){
        this.showOrgSelection = true
      }
      this.onLoadUserConfig()
      this.getOrgData().then(res => {
        this.orgTreeData = res.data
      })
    },
    methods: {
      ...mapMutations('userManage',['SET_CURRENT','SET_PAGE', 'SET_ORDER']),
      ...mapActions('userManage', [
          'getUserList',
          'addUserList',
          'updateUserList',
          'deleteUserList',
          'updateUser',
          'getUserData',
          'setUserData',
          'getUserMenu',
          'setUserMenu',
          'getDSNList',
          'getAllRoleList',
        ]),
      ...mapActions('menuManage', ['getMenuList']),
      ...mapActions('orgManage',['getOrgData']),
      // 保存
      onSubmit () {
        this.$refs.ruleForm.validate(valid => {
          if (valid) {
            delete this.form.data.password2
            let formVal = {...this.form.data, active: this.form.data.active ? 1 : 0}
            this.form.statusBtn = true
            this.form.loadingBtn = true
            if (formVal.id) {
              this.updateUser({...formVal})
                .then((res) =>  {
                  this.visible = false
                  this.$message.success('用户修改成功')
                  this.getUserList()
                })
                .catch(err => this.$message.error('用户修改失败，原因：' + err.msg + '！'))
                .finally(() => {
                  this.form.loadingBtn = false
                  this.form.statusBtn = false
                })
            } else {
              if (!this.showOrgSelection){
                formVal.orgIds = [store.getters.selectedOrg.id]
              }
              this.addUserList({...formVal})
                .then((res) =>  {
                  this.visible = false
                  this.$message.success('用户创建成功')
                  this.getUserList()
                })
                .catch(err => this.$message.error('用户创建失败，原因：' + err.msg + '！'))
                .finally(() => {
                  this.form.loadingBtn = false
                  this.form.statusBtn = false
                })
            }
          } else {
            setTimeout(()=>{
              this.form.loadingBtn = false
              this.form.statusBtn = false
              return false
            }, 1500)
          }
        })
      },
      onTreeSelectChange () {},
      // 创建
      onSetUpUser () {
        this.visible = true
        this.title = '新增用户'
        this.currentShow = 'user'
      },
      // 关闭抽屉
      onClose () {
        this.visible = false
      },
      order_way (order) {
        if (order == 'ascend') {
          return 'asc'
        } else if(order == 'descend') {
          return 'desc'
        } else {
          return ''
        }
      },
      // 分页-每页条数
      onTableHandle (page, filters, {field, order}) {
        const orderObj = {
          order: this.order_way(order),
          orderBy: field || ''
        }
        this.SET_CURRENT(page.current)
        this.SET_PAGE(page.pageSize)
        this.SET_ORDER({...orderObj})
        this.getUserList()
      },
      // 获取修改行
      onUpdateUser (row) {
        this.title='修改用户'
        this.currentShow = 'user'
        this.visible = true
        this.updateUserList(row.id)
          .then((res) => {
            let orgIds = res.data.orgs.map(org => org.id)
            this.form.data = {...res.data, active: res.data.active == 1? true: false, orgIds: orgIds}
          })
          .catch((err) => this.$message.error('获取修改用户信息失败，原因：' + err.msg + '！'))
      },
      // 获取删除行
      onDeleteUser (row) {
        this.$confirm({
          title: '删除提示',
          content: '删除用户信息无法恢复，您确定要继续吗？',
          okText: '确定',
          cancelText: '取消',
          onOk: () => {
            this.deleteUserList(row.id)
              .then(()=>{
                this.getUserList()
                this.$message.success('用户删除成功')
              })
              .catch((err) => this.$message.error('用户删除失败，原因：' + err.msg + '！'))
          },
          onCancel: () => {},
        })
      },
      handleChange (val) {
        this.permissionForm.data.permission = [...val]
      },
      // 保存数据源权限 / 保存菜单权限
      onSubmitUserPermission () {
        this.permissionForm.loadingBtn = true
        this.permissionForm.statusBtn = true
        if (this.currentShow == 'data') {
          this.setUserData({...this.permissionForm.data})
            .then(() => {
              this.$message.success('用户数据源权限分配成功')
              this.permissionForm.isLook = true
            })
            .catch((err) => this.$message.error('用户数据源权限分配失败，原因：' + err.msg + '！'))
            .finally(res => {
              this.permissionForm.loadingBtn = false
              this.permissionForm.statusBtn = false
            })
        } else {
          this.setUserMenu({...this.permissionForm.menu})
            .then(() => {
              this.$message.success('用户菜单权限分配成功')
              this.permissionForm.isLook = true
            })
            .catch((err) => this.$message.error('用户菜单权限分配失败，原因：' + err.msg + '！'))
            .finally(res => {
              this.permissionForm.loadingBtn = false
              this.permissionForm.statusBtn = false
            })
        }
      },
      //
      onAgainSetUserPermission () {
        this.permissionForm.isLook = false
      },
      onQueryUserData (row) {
        this.title = '当前用户数据源权限'
        this.currentShow = 'data'
        this.permissionForm.isLook = true
        this.visible = true
        this.getUserData(row.id)
          .then(res => {
            this.permissionForm.data.permission = res.data
            this.permissionForm.data.id = row.id
          })
          .catch(err => {
            this.$message.error('请求数据出现错误，原因：'+ err.msg +'！')
          })
      },
      onQueryUserMenu (row) {
        this.title = '当前用户菜单权限'
        this.currentShow = 'menu'
        this.permissionForm.isLook = true
        this.visible = true
        this.getUserMenu(row.id)
          .then(res => {
            this.permissionForm.menu.permission = res.data
            this.permissionForm.menu.id = row.id
          })
          .catch(err => {
            this.$message.error('请求数据出现错误，原因：'+ err.msg +'！')
          })
      },
      generateTree (data) {
        const nodeMap = {}
        const nodes = []
        const treeData = []
        data.forEach((item, index) => {
          const node = {}
          node.title = item.name
          node.key = item.id
          node.value = item.id
          if (item.parent) {
            node.parent = item.parent
          }
          if(item.children && item.children.length) {
            node.children = item.children
          }else{
            node.children = []
          }
          nodeMap[item.id] = node
          nodes.push(node)
        })
        nodes.forEach((item) => {
          let arr = []
          for (const key in nodeMap) {
            let children = item.children
            for (let i = 0; i < children.length; i++) {
              if (children[i].parent == key) {
                let node = {}
                node.title = children[i].name
                node.key = children[i].id
                node.value = children[i].id
                arr.push(node)
              }
            }
          }
          treeData.push({...item, children: arr})
        })
        return treeData
      },
      // 初始化加载页面数据
      onLoadUserConfig () {
        this.table_loading = true;
        this.getUserList()
          .then(res =>{
          })
          .catch(err =>{
            if (err.code == 401) {
              this.err401(err)
              return
            }
            this.$message.error('获取用户列表失败，原因：' + err.msg + '！')
          })
          .finally(res =>{
            this.table_loading = false;
          })
        this.getAllRoleList()
          .then(res =>{
            const {data} = res.data
            this.roleList = data
          })
          .catch(err =>{
            this.$message.error('获取角色列表失败，原因：' + err.msg + '！')
          })
      }
    }
  }
</script>

<style scoped>
.user_list {
  width: 100%;
  height: 100%;
}
.ant-drawer>>>.ant-drawer-body{
  height: calc(100% - 55px);
}

.ant-form{
  height: 100%;
  display: flex;
  flex-direction: column;
}

.submit_style{
  margin-bottom: 0;
  flex: 1;
}

.submit_style>>>.ant-col.ant-col-18.ant-form-item-control-wrapper{
  width: 100%;
  height: 100%;
}

.submit_style>>>.ant-form-item-control{
  display: flex;
  height: 100%;
  align-items: flex-end;
}

.submit_style>>>span.ant-form-item-children{
  width: 100%;
}

.save_button,
.cancal_button {
  float: right;
}

.cancal_button {
  margin-right: 15px;
}

.checkbox_group{
  display: flex;
  flex-direction: column;
}

.ant-checkbox-wrapper + .ant-checkbox-wrapper {
  margin-left: 0;
}

label.ant-checkbox-wrapper{
  display: flex;
  align-items: center;
}

.user_title{
  display: flex;
  justify-content: space-between;
}


.user_title span {
  display: block;
  float: left;
  margin-bottom: 0;
  padding-right: 12px;
  color: rgba(0,0,0,.85);
  font-weight: 500;
  font-size: 16px;
  line-height: 32px;
}

.user_action{
  font-size: 12px;
}

.user_action a {
  line-height: 25px;
}

.ant-table-wrapper>>>td.ant-table-row-cell-break-word {
  padding: 10px;
}

.user_list >>> ul.ant-pagination.ant-table-pagination {
  width: 100%;
  display: flex;
}

.user_list >>> ul.ant-pagination.ant-table-pagination>li.ant-pagination-total-text {
  flex: 1;
  text-indent: 10px;
  font-size: 14px;
  color: #999;
}

.user_list >>> .ant-table-body { white-space: nowrap; }
</style>
